home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / var / lib / python-support / python2.6 / orca / keybindings.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  10.3 KB  |  289 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''Provides support for defining keybindings and matching them to input
  5. events.'''
  6. __id__ = '$Id: keybindings.py 3971 2008-06-11 00:54:46Z joanied $'
  7. __version__ = '$Revision: 3971 $'
  8. __date__ = '$Date: 2008-06-10 20:54:46 -0400 (Tue, 10 Jun 2008) $'
  9. __copyright__ = 'Copyright (c) 2005-2008 Sun Microsystems Inc.'
  10. __license__ = 'LGPL'
  11.  
  12. try:
  13.     import gtk
  14. except ImportError:
  15.     pass
  16.  
  17. import pyatspi
  18. import debug
  19. import settings
  20. import orca_state
  21. from orca_i18n import _
  22. _keysymsCache = { }
  23. _keycodeCache = { }
  24.  
  25. def getAllKeysyms(keysym):
  26.     '''Given a keysym, find all other keysyms associated with the key
  27.     that is mapped to the given keysym.  This allows us, for example,
  28.     to determine that the key bound to KP_Insert is also bound to KP_0.'''
  29.     if keysym not in _keysymsCache:
  30.         _keysymsCache[keysym] = [
  31.             keysym]
  32.         keyval = gtk.gdk.keyval_from_name(keysym)
  33.         if keyval != 0:
  34.             keymap = gtk.gdk.keymap_get_default()
  35.             entries = keymap.get_entries_for_keyval(keyval)
  36.             keycode = 0
  37.             if entries:
  38.                 for entry in entries:
  39.                     if entry[1] == 0:
  40.                         keycode = entry[0]
  41.                         break
  42.                         continue
  43.                 
  44.             
  45.             if keycode != 0:
  46.                 entries = keymap.get_entries_for_keycode(keycode)
  47.                 if entries:
  48.                     for entry in entries:
  49.                         keyval = entry[0]
  50.                         name = gtk.gdk.keyval_name(keyval)
  51.                         if name and name != keysym:
  52.                             _keysymsCache[keysym].append(name)
  53.                             continue
  54.                     
  55.                 
  56.             
  57.         
  58.     
  59.     return _keysymsCache[keysym]
  60.  
  61.  
  62. def getKeycode(keysym):
  63.     """Converts an XKeysym string (e.g., 'KP_Enter') to a keycode that
  64.     should match the event.hw_code for key events.
  65.  
  66.     This whole situation is caused by the fact that Solaris chooses
  67.     to give us different keycodes for the same key, and the keypad
  68.     is the primary place where this happens: if NumLock is not on,
  69.     there is no telling the difference between keypad keys and the
  70.     other navigation keys (e.g., arrows, page up/down, etc.).  One,
  71.     for example, would expect to get KP_End for the '1' key on the
  72.     keypad if NumLock were not on.  Instead, we get 'End' and the
  73.     keycode for it matches the keycode for the other 'End' key.  Odd.
  74.     If NumLock is on, we at least get KP_* keys.
  75.  
  76.     So...when setting up keybindings, we say we're interested in
  77.     KeySyms, but those keysyms are carefully chosen so as to result
  78.     in a keycode that matches the actual key on the keyboard.  This
  79.     is why we use KP_1 instead of KP_End and so on in our keybindings.
  80.  
  81.     Arguments:
  82.     - keysym: a string that is a valid representation of an XKeysym.
  83.  
  84.     Returns an integer representing a key code that should match the
  85.     event.hw_code for key events.
  86.     """
  87.     if not keysym:
  88.         return 0
  89.     return _keycodeCache[keysym]
  90.  
  91.  
  92. def getModifierNames(mods):
  93.     '''Gets the modifier names of a numeric modifier mask as a human
  94.     consumable string.
  95.     '''
  96.     text = ''
  97.     if mods & settings.ORCA_MODIFIER_MASK:
  98.         text += _('Orca') + '+'
  99.     
  100.     if mods & 128:
  101.         text += _('Alt_R') + '+'
  102.     
  103.     if mods & 1 << pyatspi.MODIFIER_META3:
  104.         text += _('Super') + '+'
  105.     
  106.     if mods & 1 << pyatspi.MODIFIER_META2:
  107.         text += _('Meta2') + '+'
  108.     
  109.     if mods & settings.ALT_MODIFIER_MASK:
  110.         text += _('Alt_L') + '+'
  111.     
  112.     if mods & settings.CTRL_MODIFIER_MASK:
  113.         text += _('Ctrl') + '+'
  114.     
  115.     if mods & 1 << pyatspi.MODIFIER_SHIFTLOCK:
  116.         text += _('Caps_Lock') + '+'
  117.     
  118.     if mods & settings.SHIFT_MODIFIER_MASK:
  119.         text += _('Shift') + '+'
  120.     
  121.     return text
  122.  
  123.  
  124. class KeyBinding:
  125.     '''A single key binding, consisting of a keycode, a modifier mask,
  126.     and the InputEventHandler.
  127.     '''
  128.     
  129.     def __init__(self, keysymstring, modifier_mask, modifiers, handler, click_count = 1):
  130.         """Creates a new key binding.
  131.  
  132.         Arguments:
  133.         - keysymstring: the keysymstring - this is typically a string
  134.           from /usr/include/X11/keysymdef.h with the preceding 'XK_'
  135.           removed (e.g., XK_KP_Enter becomes the string 'KP_Enter').
  136.         - modifier_mask: bit mask where a set bit tells us what modifiers
  137.           we care about (see pyatspi.MODIFIER_*)
  138.         - modifiers: the state the modifiers we care about must be in for
  139.           this key binding to match an input event (see also
  140.           pyatspi.MODIFIER_*)
  141.         - handler: the InputEventHandler for this key binding
  142.         """
  143.         self.keysymstring = keysymstring
  144.         self.modifier_mask = modifier_mask
  145.         self.modifiers = modifiers
  146.         self.handler = handler
  147.         self.click_count = click_count
  148.         self.keycode = None
  149.  
  150.     
  151.     def matches(self, keycode, modifiers):
  152.         '''Returns true if this key binding matches the given keycode and
  153.         modifier state.
  154.         '''
  155.         if not self.keycode:
  156.             self.keycode = getKeycode(self.keysymstring)
  157.         
  158.         if self.keycode == keycode:
  159.             result = modifiers & self.modifier_mask
  160.             return result == self.modifiers
  161.         return False
  162.  
  163.  
  164.  
  165. class KeyBindings:
  166.     '''Structure that maintains a set of KeyBinding instances.
  167.     '''
  168.     
  169.     def __init__(self):
  170.         self.keyBindings = []
  171.  
  172.     
  173.     def __str__(self):
  174.         result = '[\n'
  175.         for keyBinding in self.keyBindings:
  176.             result += '  [%x %x %s %d %s]\n' % (keyBinding.modifier_mask, keyBinding.modifiers, keyBinding.keysymstring, keyBinding.click_count, keyBinding.handler.description)
  177.         
  178.         result += ']'
  179.         return result
  180.  
  181.     
  182.     def add(self, keyBinding):
  183.         '''Adds the given KeyBinding instance to this set of keybindings.
  184.         '''
  185.         self.keyBindings.append(keyBinding)
  186.  
  187.     
  188.     def remove(self, keyBinding):
  189.         '''Removes the given KeyBinding instance from this set of keybindings.
  190.         '''
  191.         for i in range(0, len(self.keyBindings)):
  192.             if keyBinding == self.keyBindings[i]:
  193.                 del self.keyBindings[i]
  194.                 continue
  195.         
  196.  
  197.     
  198.     def removeByHandler(self, handler):
  199.         '''Removes the given KeyBinding instance from this set of keybindings.
  200.         '''
  201.         i = len(self.keyBindings)
  202.         while i > 0:
  203.             if self.keyBindings[i - 1].handler == handler:
  204.                 del self.keyBindings[i - 1]
  205.             
  206.             i = i - 1
  207.  
  208.     
  209.     def hasKeyBinding(self, newKeyBinding, typeOfSearch = 'strict'):
  210.         '''Return True if keyBinding is already in self.keyBindings.
  211.  
  212.            The typeOfSearch can be:
  213.               "strict":      matches description, modifiers, key, and
  214.                              click count
  215.               "description": matches only description.
  216.               "keys":        matches the modifiers, key, and modifier mask,
  217.                              and click count
  218.               "keysNoMask":  matches the modifiers, key, and click count
  219.         '''
  220.         hasIt = False
  221.         for keyBinding in self.keyBindings:
  222.             if typeOfSearch == 'strict':
  223.                 if keyBinding.handler.description == newKeyBinding.handler.description and keyBinding.keysymstring == newKeyBinding.keysymstring and keyBinding.modifier_mask == newKeyBinding.modifier_mask and keyBinding.modifiers == newKeyBinding.modifiers and keyBinding.click_count == newKeyBinding.click_count:
  224.                     hasIt = True
  225.                 
  226.             keyBinding.click_count == newKeyBinding.click_count
  227.             if typeOfSearch == 'description':
  228.                 if keyBinding.handler.description == newKeyBinding.handler.description:
  229.                     hasIt = True
  230.                 
  231.             keyBinding.handler.description == newKeyBinding.handler.description
  232.             if typeOfSearch == 'keys':
  233.                 if keyBinding.keysymstring == newKeyBinding.keysymstring and keyBinding.modifier_mask == newKeyBinding.modifier_mask and keyBinding.modifiers == newKeyBinding.modifiers and keyBinding.click_count == newKeyBinding.click_count:
  234.                     hasIt = True
  235.                 
  236.             keyBinding.click_count == newKeyBinding.click_count
  237.             if typeOfSearch == 'keysNoMask':
  238.                 if keyBinding.keysymstring == newKeyBinding.keysymstring and keyBinding.modifiers == newKeyBinding.modifiers and keyBinding.click_count == newKeyBinding.click_count:
  239.                     hasIt = True
  240.                 
  241.             keyBinding.click_count == newKeyBinding.click_count
  242.         
  243.         return hasIt
  244.  
  245.     
  246.     def getInputHandler(self, keyboardEvent):
  247.         '''Returns the input handler of the key binding that matches the
  248.         given keycode and modifiers, or None if no match exists.
  249.         '''
  250.         if not orca_state.activeScript:
  251.             return None
  252.         candidates = []
  253.         clickCount = orca_state.activeScript.getClickCount()
  254.         for keyBinding in self.keyBindings:
  255.             if keyBinding.matches(keyboardEvent.hw_code, keyboardEvent.modifiers):
  256.                 if keyBinding.modifier_mask == keyboardEvent.modifiers and keyBinding.click_count == clickCount:
  257.                     return keyBinding.handler
  258.                 candidates.append(keyBinding)
  259.                 continue
  260.             keyBinding.click_count == clickCount
  261.         
  262.         candidates.sort(cmp = (lambda x, y: x.click_count - y.click_count), reverse = True)
  263.         for candidate in candidates:
  264.             if candidate.click_count <= clickCount:
  265.                 return candidate.handler
  266.         
  267.  
  268.     
  269.     def consumeKeyboardEvent(self, script, keyboardEvent):
  270.         '''Attempts to consume the given keyboard event.  If these
  271.         keybindings have a handler for the given keyboardEvent, it is
  272.         assumed the event will always be consumed.
  273.         '''
  274.         consumed = False
  275.         handler = self.getInputHandler(keyboardEvent)
  276.         if handler:
  277.             consumed = True
  278.             if keyboardEvent.type == pyatspi.KEY_PRESSED_EVENT:
  279.                 
  280.                 try:
  281.                     handler.processInputEvent(script, keyboardEvent)
  282.                 debug.printException(debug.LEVEL_SEVERE)
  283.  
  284.             
  285.         
  286.         return consumed
  287.  
  288.  
  289.